


PM_FUNC_NORM_ATTRIB DamageFake( Int:victim, Int:attacker, Int:damage, String:szAttack[], PM_TYPE:attackType, PM_TYPE:victimType )
{
	if ( g_iState == PM_DISABLED )
		return 0;

	if ( !PlayerGetInfo( attacker, PINFO_CONNECT ) )
		return 0;

	//if it's not a player we're attacking
	if ( !is_user_alive( victim ) )
	{
		//if the entity is valid
		if ( EntityValid( victim ) )
		{
			new Float:fTakeDamage;
			pev( victim, pev_takedamage, fTakeDamage );
			//if the entity takes damage and damage is successful
			if ( fTakeDamage && fm_fakedamage( victim, szAttack, float( damage ), DMG_GENERIC ) )
				return damage;
		}
		return 0;
	}

	//if it heals, don't bother with anything, just heal them
	if ( damage < 0 )
	{
		new Float:fMaxHealth; pev( victim, pev_max_health, fMaxHealth );
		new Int:iMaxHealth = floatround( fMaxHealth );
		new Int:iHealth = get_user_health( victim );

		if ( iHealth - damage > iMaxHealth )
		{
			set_user_health( victim, iMaxHealth );
			return iHealth - iMaxHealth;
		}

		set_user_health( victim, iHealth - damage );
		return -1 * damage;
	}

	new Int:victimHealth = get_user_health( victim );
	damage = floatround( damage * TypeMultiplier( attackType, victimType ), floatround_ceil );

	new bool:bTeamAttack = ( cs_get_user_team(victim) == cs_get_user_team(attacker) ) ? true : false;

	//Damage altertions
	{
		//Only allow team attacks if friendly fire is on
		if ( bTeamAttack && !get_pcvar_num( mp_friendlyfire ) )
			damage = 0;

		//Don't damage if they have god mode
		else if ( get_user_godmode( victim ) )
			damage = 0

		//Don't allow us to hurt players during freezetime
		else if ( g_iRoundState & ROUND_FREEZETIME )
			damage = 0;
	}

	if ( !damage )
		return 0

	// *** Damage calculation due to armor from: multiplayer/dlls/player.cpp ***
	new Float:fDamage = damage * SettingGetFloat( ARMOR_RATIO );
	new Float:fArmorBonus = SettingGetFloat( ARMOR_BONUS );
	new Float:fArmorDamage = ( float( damage ) - fDamage ) * fArmorBonus;
	new Int:iArmor = get_user_armor( victim );

	// Does this use more armor than we have figured for?
	if ( fArmorDamage > iArmor )
	{
		fArmorDamage = iArmor / fArmorBonus;
		fDamage = damage - fArmorDamage;
		iArmor = 0;
	}
	else
	{
		iArmor -= floatround( fArmorDamage, floatround_ceil );
	}

	CoreCallValues( .iVictim = victim,
					.iAttacker = attacker,
					.fDamage = fDamage,
					.iWeaponID = 0
					);

	SkillCallType( CALL_TAKE_POKEDAMAGE, victim );
	SkillCallType( CALL_GIVE_POKEDAMAGE, attacker );

	victim = g_iVictim;
	attacker = g_iAttacker;
	fDamage = g_fDamage;

	CoreCallRestoreValues();

	if ( !fDamage )
		return 0;

	damage = floatround( fDamage );
	new Int:iNewHP = victimHealth - damage;

	PokemonGiveDamage( attacker );
	PokemonTakeDamage( victim, PlayerGetInfo( victim, PINFO_ACTIVE_POKENUM ), damage );

	//wake them up if they were sleeping
	if ( g_iPlayerStatus[ victim ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] > 0 && !equali( szAttack, "Dream Eat" ) && !equali( szAttack, "Poison" ) && SettingGetNum( POKEDAMAGE_AWAKEN ) )
		g_iPlayerStatus[ victim ][ STATUS_ASLEEP ][ STATUS_AMOUNT ] = 0;

	set_pev( victim, pev_dmg_inflictor, attacker );

	//if they should die
	if ( iNewHP <= 0 )
	{
		//Kill the victim and block the messages
		set_msg_block( g_msgDeathMsg, BLOCK_ONCE );
		set_msg_block( g_msgScoreInfo, BLOCK_ONCE );

		new Int:iForwardID = register_forward( FM_AlertMessage, "ForwardAlertMessage" );
		user_kill( victim );
		unregister_forward( FM_AlertMessage, iForwardID );

		if ( !is_user_alive( victim ) )
		{
			DamageKill( victim, attacker, szAttack, bTeamAttack );
			return damage;
		}
	}

	//they didn't die
	DamageLog( attacker, victim, szAttack, "body", damage, iNewHP );

	if ( bTeamAttack && damage > 0 )
	{
		new String:szAttackerName[32];
		PlayerToName( attacker, szAttackerName, charsmax(szAttackerName) );

		client_print( 0, print_chat, "%s attacked a teammate", szAttackerName );
	}

	set_user_health( victim, iNewHP );
	set_user_armor( victim, iArmor );

	new Coord:cOrigin[3];
	get_user_origin( attacker, cOrigin );

	//Damage message
	message_begin( MSG_ONE_UNRELIABLE, g_msgDamage, _, victim );
	write_byte( 0 ); // dmg_save
	write_byte( damage ); // dmg_take
	write_long( 0 ); // visibleDamageBits
	write_coord( cOrigin[0] ); // damageOrigin.x
	write_coord( cOrigin[1] ); // damageOrigin.y
	write_coord( cOrigin[2] ); // damageOrigin.z
	message_end();

	return damage
}

PM_FUNC_NORM_ATTRIB DamageKill( Int:victim, Int:attacker, String:Attack[], bool:bTeamAttack )
{
	//don't need to give kill xp since we resend the death message, so the kill xp is given in the other death event
	//KillXP(attacker, victim)

	//make them view who killed them
	set_pev( victim, pev_iuser3, attacker );

	DamageKillLog( attacker, victim, Attack );

	new Int:attackerFrags = get_user_frags( attacker );
	new Int:victimFrags = get_user_frags( victim );

	PlayerGiveMoney( attacker, bTeamAttack ? -300 : 300 );

	set_user_frags( attacker, bTeamAttack ? --attackerFrags : ++attackerFrags );

	if ( bTeamAttack )
	{
		client_print( attacker, print_center, "You killed a teammate" );
		set_user_frags( victim, ++victimFrags );
	}

	//Replaced HUD death message
	emessage_begin( MSG_BROADCAST, g_msgDeathMsg );
	ewrite_byte( attacker );
	ewrite_byte( victim );
	ewrite_byte( 0 );
	ewrite_string( Attack );
	emessage_end();

	//Update killers scorboard with new info
	emessage_begin( MSG_BROADCAST, g_msgScoreInfo );
	ewrite_byte( attacker );
	ewrite_short( attackerFrags );
	ewrite_short( get_user_deaths( attacker ) );
	ewrite_short( 0 );
	ewrite_short( _:cs_get_user_team( attacker ) );
	emessage_end();

	//Update victims scoreboard with correct info
	emessage_begin( MSG_BROADCAST, g_msgScoreInfo );
	ewrite_byte( victim );
	ewrite_short( victimFrags );
	ewrite_short( get_user_deaths( victim ) );
	ewrite_short( 0 );
	ewrite_short( _:cs_get_user_team( victim ) );
	emessage_end();
}

PM_FUNC_NORM_ATTRIB DamageKillLog( Int:attacker, Int:victim, String:szWeapon[] )
{
	// Info On Attacker
	new String:szAttackerName[32], String:szAttackerAuth[34], String:szAttackerTeam[32];
	PlayerToName( attacker, szAttackerName, charsmax(szAttackerName) );
	get_user_team( attacker, szAttackerTeam, charsmax(szAttackerTeam) );
	get_user_authid( attacker, szAttackerAuth, charsmax(szAttackerAuth) );

	// Log This Kill
	if ( attacker == victim )
	{
		log_message( "^"%s<%d><%s><%s>^" killed self with ^"%s^"",
			szAttackerName, get_user_userid(attacker), szAttackerAuth, szAttackerTeam,
			szWeapon );
	}
	else
	{
		// Info On Victim
		new String:szVictimName[32], String:szVictimAuth[34], String:szVictimTeam[32];
		PlayerToName( victim, szVictimName, charsmax(szVictimName) );
		get_user_team( victim, szVictimTeam, charsmax(szVictimTeam) );
		get_user_authid( victim, szVictimAuth, charsmax(szVictimAuth) );

		log_message( "^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"%s^"",
			szAttackerName, get_user_userid(attacker), szAttackerAuth, szAttackerTeam,
			szVictimName, get_user_userid(victim), szVictimAuth, szVictimTeam,
			szWeapon );
	}
}

PM_FUNC_NORM_ATTRIB DamageLog( Int:attacker, Int:victim, String:szWeapon[], String:szHit[], Int:damage, Int:health )
{
	if ( get_pcvar_num( mp_logdetail ) != 3 )
		return;

	// Info On Attacker
	new String:szAttackerName[32], String:szAttackerAuth[34], String:szAttackerTeam[32];
	PlayerToName( attacker, szAttackerName, charsmax(szAttackerName) );
	get_user_team( attacker, szAttackerTeam, charsmax(szAttackerTeam) );
	get_user_authid( attacker, szAttackerAuth, charsmax(szAttackerAuth) );

	// Info On Victim
	new String:szVictimName[32], String:szVictimAuth[34], String:szVictimTeam[32];
	PlayerToName( victim, szVictimName, charsmax(szVictimName) );
	get_user_team( victim, szVictimTeam, charsmax(szVictimTeam) );
	get_user_authid( victim, szVictimAuth, charsmax(szVictimAuth) );

	// Log This Damage
	log_message("^"%s<%d><%s><%s>^" attacked ^"%s<%d><%s><%s>^" with ^"%s^" (hit ^"%s^") (damage ^"%d^") (health ^"%d^")",
		szAttackerName, get_user_userid(attacker), szAttackerAuth, szAttackerTeam,
		szVictimName, get_user_userid(victim), szVictimAuth, szVictimTeam,
		szWeapon, szHit, damage, health );
}


